home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
c
/
xmsif15.zip
/
XMSTEST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-10
|
59KB
|
1,327 lines
/***************************************************************************
* xmstest.c *
* MODULE: XMSIF *
* OS: DOS *
* VERSION: 1.3 *
* DATE: 05/09/93 *
* *
* Copyright (c) 1993 James W. Birdsall. All Rights Reserved. *
* *
* Requires xmsif.h, testutil.h, and xmstest.h to compile. *
* Compiles under Borland C++ 2.0, Turbo C 2.0, MSC 6.00A, MSC/C++ 7.0. *
* *
* Regression test and example for XMSIF. *
* *
* This file is part one of the regression tester and example for XMSIF. *
* The other parts are named EMSTEST2.C and EMSTEST3.C. All three parts *
* must be compiled and linked together along with the appropriate XMSIF *
* library to produce the tester executable. This program compiles under *
* tiny, small, medium, compact, large, and huge models. *
* *
* To use this tester: in general, just run it. Depending on what XMS *
* driver you have, you may need to use the "-q" option. HIMEM.SYS does *
* not require this option; QEMM 5.1* does; I don't know about other XMS *
* drivers. If you haven't used it and should, or should use it and *
* haven't, the tester can detect this and will abort with a message *
* suggesting you do the opposite of whatever you did. For more detail on *
* what this option actually does, see below. The tester produces output *
* on stdout. It performs 70+ tests, depending on the exact configuration *
* of your system, and parts of it run quite fast. If you want to read *
* all the output, you should redirect the output to a file (but first *
* you should probably run it straight to get an idea of how long it *
* takes on your machine). If you just want to see whether the tests all *
* pass, just run it -- if a test fails, execution aborts immediately. *
* *
* Certain types of failure may cause XMSTEST to not deallocate memory *
* that it has allocated. This should only occur if the library itself is *
* malfunctioning (which should never happen to you, only to me!) or if *
* you are trying a different compiler or unsupported memory model and *
* the compiler and library are therefore not communicating properly. It *
* may also happen if you press control-break. *
* *
* *
* The actions XMSTEST takes may be broken down into two parts: EMB tests *
* and UMB tests. In the first part, it tests the XMM* functions which *
* operate on extended memory blocks (EMBs). In the second part, it tests *
* the UMB* functions which operate on upper memory blocks (UMBs). Before *
* doing any of this, it tries to initialize XMSIF, which checks for the *
* presence of an XMS driver, and aborts if there isn't one. Then it *
* starts the first part, performing various preliminary tests on EMBs. *
* If it determines that there isn't a large enough EMB free, it reports *
* this and skips the copying function tests (tests of _XMMcopy() and *
* _XMMicopy()), otherwise it performs the copying function tests. Then *
* it starts the second part by trying to determine whether your system *
* has UMBs. If it does not, it reports this fact and skips the rest of *
* the UMB tests. If it does, it performs the rest of the UMB tests. If *
* you see a message about "another broken system", that means that your *
* XMS driver's support of UMBs is somewhat flaky, and the workarounds *
* already built into XMSIF were unable to cover the problem. In this *
* case, it will perform the rest of the UMB tests but is unable to check *
* that the functions actually did anything -- i.e. it can check the *
* return code from the function, but cannot independently verify via *
* other functions that the desired effect was actually achieved. See the *
* XMSIF documentation for a description of problems seen in the UMB *
* support of various XMS drivers. *
* *
* The "-q" option covers for some unusual behavior observed in QEMM *
* 5.1x which may also occur in other XMS drivers which provide EMS *
* services as well. In QEMM's case, when extended memory is allocated, *
* the total amount of XMS still available is decreased by the allocation *
* size rounded up to the nearest _16K_ (the EMS page size) instead of to *
* the nearest 1K (the XMS minimum allocation unit). HIMEM.SYS does not *
* display this behavior. The "-q" option tells XMSTEST to expect a drop *
* of a multiple of 16K after an allocation instead of a multiple of 1K. *
* While XMSTEST can easily detect the difference, this option was added *
* so that XMSTEST would know which multiple was expected and could *
* detect incorrect drops more reliably. *
* *
* The "-w" option covers for some different unusual behavior observed *
* in DOS windows running under MS Windows 3.1 (it is not known whether *
* Windows 3.0 does the same thing). In this case, when extended memory *
* is allocated, the total amount of XMS still available is decreased by *
* the allocation size rounded up to the nearest _4K_ (the 803/486 memory *
* management page size). The "-w" option tells XMSTEST to expect a drop *
* of a multiple of 4K after an allocation instead of a multiple of 1K. *
* While XMSTEST can easily detect the difference, this option was added *
* so that XMSTEST would know which multiple was expected and could *
* detect incorrect drops more reliably. *
* *
* The "-3" option indicates that XMSTEST is running on a 386 or better *
* and hence can test the XMMraw3() function safely (if the XMS version *
* is 3.0 or better). *
* *
* *
* Turbo C and older versions of Turbo C++ do not have the _fmemcmp() and *
* _fmemset() functions; I don't know about older versions of MSC. If *
* your compiler does not have these functions, define the symbol *
* NO_FFUNC and functions in this file will be used instead. *
* *
***************************************************************************/
/*
** system includes <>
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <ctype.h>
/*
** custom includes ""
*/
#include "xmsif.h"
#include "xmstest.h"
#include "testutil.h"
/*
** local #defines
*/
/*
** misc: copyright strings, version macros, etc.
*/
/*
** typedefs
*/
/*
** global variables
*/
int testno = 1; /* number of test currently being done */
char *gblmsg = ""; /* msg to be printed in test header */
int qflag = 0; /* running QEMM or not? */
int wflag = 0; /* running under Windows or not? */
int on386 = 0; /* running on a 386+ or not? */
/*
** static globals
*/
/*
** function prototypes
*/
/*
** functions
*/
/***************************************************************************
* FUNCTION: MAIN *
* *
* DESCRIPTION: *
* *
* The master function. *
* *
* ENTRY: *
* *
* None. *
* *
* EXIT: *
* *
* Void. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
main(int argc, char *argv[])
{
int status; /* return status from library functions */
unsigned int version;
int i;
for (i = 1; i < argc; i++)
{
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
if (toupper(argv[i][1]) == 'Q')
{
qflag = 1;
}
else if (toupper(argv[i][1]) == 'W')
{
wflag = 1;
}
else if (argv[i][1] == '3')
{
on386 = 1;
}
else
{
printf("Usage: XMSTEST [-wq3]\n");
exit(1);
}
}
else
{
printf("Usage: XMSTEST [-wq3]\n");
exit(1);
}
}
/* set banner */
gblmsg = " PRELIMINARY EMB TESTS";
/*
** check initialization test
*/
TESTHEADER();
printf("Making a call to XMMgetversion() before calling XMMlibinit().\n");
printf("The call should fail.\n");
XMMgetversion();
nofailcheck("XMMgetversion()", (int) _XMMerror, (void far *) NULL, 0, 0);
weirdcodechk("XMMgetversion()", XMM_NOINIT, (void far *) NULL, 0, 0);
TESTTAILER();
/*
** initialize XMSIF
*/
TESTHEADER();
printf("Calling XMMlibinit().\n");
printf("Should succeed if Extended Memory Manager is present.\n");
status = XMMlibinit();
switch (status)
{
case XMMOOPS:
printf("XMMlibinit() failed, code 0x%X.\n",
(unsigned int) _XMMerror);
exit(3);
break;
case NOXMM:
printf("XMMlibinit() did not find an Extended Memory Manager.\n");
exit(3);
break;
case 0:
printf("XMMlibinit() returned OK.\n");
weirdcodechk("XMMlibinit()", 0, (void far *) NULL, 0, 0);
break;
default:
printf("XMMlibinit() returned strange value %d.\n", status);
exit(3);
break;
}
TESTTAILER();
/*
** test version call
*/
TESTHEADER();
printf("Testing XMMgetversion().\n");
printf("Results should match value in _XMMversion.\n");
version = XMMgetversion();
weirdcodechk("XMMgetversion()", 0, (void far *) NULL, 0, 0);
if (version != (int) _XMMversion)
{
printf("XMMgetversion() [0x%X] and _XMMversion [0x%X] differ.\n",
version, (unsigned int) _XMMversion);
exit(3);
}
printf("XMS version %d.%02d.\n", ((version >> 8) & 0xFF), (version & 0xFF));
TESTTAILER();
/*
** test allocation functions
*/
if (do_alloc_tests(1L) == 0)
{
do_alloc_tests(16384L);
do_alloc_tests(81111L);
do_alloc_tests(0L);
/*
** test rawcall interface
*/
do_rawcall_tests();
/*
** test copies
*/
do_copy_tests();
}
/*
** test UMB functions (if possible)
*/
do_UMB_tests();
/* end and cleanup */
printf(">>>END\n");
printf("All tests succeeded.\n");
exit(0);
} /* end of main() */
/***************************************************************************
* FUNCTION: DO_ALLOC_TESTS *
* *
* DESCRIPTION: *
* *
* This function tests XMSIF calls XMMcoreleft(), XMMallcoreleft(), *
* XMMalloc(), XMMrealloc(), and XMMfree(). * *
* *
* ENTRY: *
* *
* bytes - number of bytes of XMS to try to allocate. *
* *
* EXIT: *
* *
* Void. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
int do_alloc_tests(unsigned long bytes)
{
unsigned long xmsfreeorig, xmsfreenow;
unsigned long xmsallfreeorig, xmsallfreenow;
unsigned long klen, mmupagelen, emspagelen;
unsigned long expected;
int handle;
long diff = ((bytes > HALFLEN) ? -20000 : 20000);
/* get bytes value rounded up to nearest K */
klen = ((bytes + 1023L) & 0xFFFFFC00);
/* get bytes value rounded up to nearest 4K */
mmupagelen = ((bytes + 4095L) & 0xFFFFF000);
/* get bytes value rounded up to nearest 16K */
emspagelen = ((bytes + 16383L) & 0xFFFFC000);
/* determine expected length */
if (qflag != 0)
{
expected = emspagelen;
}
else if (wflag != 0)
{
expected = mmupagelen;
}
else
{
expected = klen;
}
/* test coreleft */
TESTHEADER();
printf("Testing XMMcoreleft().\n");
printf("Result should be multiple of 1024.\n");
xmsfreeorig = test_XMMcoreleft();
printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsfreeorig, (xmsfreeorig / 1024L));
TESTTAILER();
/* test allcoreleft */
TESTHEADER();
printf("Testing XMMallcoreleft().\n");
printf("Result should be multiple of 1024 and >= XMMcoreleft().\n");
xmsallfreeorig = test_XMMallcoreleft();
if (xmsallfreeorig >= xmsfreeorig)
{
printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsallfreeorig, (xmsallfreeorig / 1024L));
}
else
{
printf("XMMallcoreleft() returned low value %lu.\n", xmsallfreeorig);
exit(3);
}
/* make sure enough free */
if (xmsallfreeorig < MINFREE)
{
printf("Insufficient free XMS to perform all tests. Aborting EMB tests.\n");
return 1;
}
/* enough free, but is it unfragmented enough to be useable? */
if (xmsfreeorig < MINFREE)
{
/* largest block isn't big enough -- can't finish tests */
printf("XMS too fragmented to perform all tests. Aborting EMB tests.\n");
return 1;
}
/* test allocation */
TESTHEADER();
printf("Testing XMMalloc(%lu).\n", bytes);
printf("Should succeed. Free XMS should drop by %lu bytes (%luK).\n",
expected, (expected / 1024L));
handle = test_XMMalloc(bytes);
printf("XMMalloc() returned OK.\n");
xmsfreenow = test_XMMcoreleft();
printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsfreenow, (xmsfreenow / 1024L));
xmsallfreenow = test_XMMallcoreleft();
printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsallfreenow, (xmsallfreenow / 1024L));
if ((xmsallfreeorig - xmsallfreenow) != expected)
{
printf("XMMalloc(%lu) caused total free to drop from %lu to %lu.\n",
bytes, xmsallfreeorig, xmsallfreenow);
if ((xmsallfreeorig - xmsallfreenow) == emspagelen)
{
if (emspagelen == mmupagelen)
{
printf("Try using the -q or -w switches.\n");
}
else
{
printf("Try using the -q switch.\n");
}
}
else if ((xmsallfreeorig - xmsallfreenow) == mmupagelen)
{
printf("Try using the -w switch.\n");
}
else if ((xmsallfreeorig - xmsallfreenow) == klen)
{
printf("Try not using the -%c switch.\n",
((qflag != 0) ? 'q' : 'w'));
}
XMMfree(handle);
exit(3);
}
TESTTAILER();
/* get realloc value rounded up to nearest K */
klen = ((bytes + diff + 1023L) & 0xFFFFFC00);
/* get realloc value rounded up to nearest 4K */
mmupagelen = ((bytes + diff + 4095L) & 0xFFFFF000);
/* get realloc value rounded up to nearest 16K */
emspagelen = ((bytes + diff + 16383L) & 0xFFFFC000);
/* determine expected value */
if (qflag != 0)
{
expected = emspagelen;
}
else if (wflag != 0)
{
expected = mmupagelen;
}
else
{
expected = klen;
}
/* test reallocation */
TESTHEADER();
printf("Testing XMMrealloc(%lu).\n", bytes + diff);
printf("Should succeed. Free XMS should now be %lu bytes (%luK) below original.\n",
expected, (expected / 1024L));
handle = test_XMMrealloc(handle, bytes + diff);
printf("XMMrealloc() returned OK.\n");
xmsfreenow = test_XMMcoreleft();
printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsfreenow, (xmsfreenow / 1024L));
xmsallfreenow = test_XMMallcoreleft();
printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsallfreenow, (xmsallfreenow / 1024L));
if ((xmsallfreeorig - xmsallfreenow) != expected)
{
printf("XMMrealloc(%lu) caused total free to be %lu.\n",
bytes, xmsallfreenow);
if ((xmsallfreeorig - xmsallfreenow) == emspagelen)
{
if (emspagelen == mmupagelen)
{
printf("Try using the -q or -w switches.\n");
}
else
{
printf("Try using the -q switch.\n");
}
}
else if ((xmsallfreeorig - xmsallfreenow) == mmupagelen)
{
printf("Try using the -w switch.\n");
}
else if ((xmsallfreeorig - xmsallfreenow) == klen)
{
printf("Try not using the -%c switch.\n",
((qflag != 0) ? 'q' : 'w'));
}
XMMfree(handle);
exit(3);
}
TESTTAILER();
/* test free */
TESTHEADER();
printf("Testing XMMfree() on handle returned by XMMalloc().\n");
printf("Should succeed. Free XMS should increase by %lu bytes (%luK).\n",
expected, (expected / 1024L));
test_XMMfree(handle);
printf("XMMfree() returned OK.\n");
xmsfreenow = test_XMMcoreleft();
printf("XMMcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsfreenow, (xmsfreenow / 1024L));
xmsallfreenow = test_XMMallcoreleft();
printf("XMMallcoreleft() returned OK, shows %lu bytes (%luK) free.\n",
xmsallfreenow, (xmsallfreenow / 1024L));
if (xmsallfreenow != xmsallfreeorig)
{
printf("Freeing handle returned by XMMalloc() did not restore\n");
printf(" total free XMS count -- was %lu originally, now %lu.\n",
xmsallfreeorig, xmsallfreenow);
exit(3);
}
TESTTAILER();
return 0;
} /* end of do_alloc_tests() */
/***************************************************************************
* FUNCTION: DO_RAWCALL_TESTS *
* *
* DESCRIPTION: *
* *
* This function tests the XMSIF calls XMMrawcall() and XMMraw3(). *
* *
* ENTRY: *
* *
* Void. *
* *
* EXIT: *
* *
* Void. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void do_rawcall_tests()
{
unsigned long xmsfree, xmsallfree;
struct XMMregs r;
int status;
/* first, get something to check against */
xmsfree = test_XMMcoreleft();
xmsallfree = test_XMMallcoreleft();
printf("XMMcoreleft: %lu bytes (%luK) XMMallcoreleft: %lu bytes (%luK)\n",
xmsfree, (xmsfree / 1024L), xmsallfree, (xmsallfree / 1024L));
TESTHEADER();
printf("Testing XMMrawcall() against XMMcoreleft()/XMMallcoreleft().\n");
printf("Should succeed.\n");
r.regAX = 0x0800;
status = XMMrawcall(&r);
TRIPLECHECK("XMMrawcall()", status, 0, (void far *) NULL, 0, 0);
if ((r.regAX != (xmsfree / 1024L)) || (r.regDX != (xmsallfree / 1024L)))
{
printf("XMMrawcall() returned %uK and %uK.\n", r.regAX, r.regDX);
exit(3);
}
TESTTAILER();
if (on386 != 0)
{
struct XMMbigregs rr;
TESTHEADER();
printf("Testing XMMraw3() against XMMcoreleft()/XMMallcoreleft().\n");
if (_XMMversion >= 0x0300)
{
printf("Should succeed.\n");
}
else
{
printf("Should fail.\n");
}
rr.regEAX = 0x00008800;
XMMraw3(&rr);
if (_XMMversion >= 0x0300)
{
weirdcodechk("XMMraw3()", 0, (void far *) NULL, 0, 0);
if ((rr.regEAX < (xmsfree / 1024L)) ||
(rr.regEDX < (xmsallfree / 1024L)))
{
printf("XMMraw3() returned %luK and %luK.\n", rr.regEAX,
rr.regEDX);
exit(3);
}
}
else if (_XMMerror != XMM_BADVERS)
{
printf("XMMraw3() returned unexpected code 0x%X.\n",
(unsigned int) _XMMerror);
exit(3);
}
TESTTAILER();
}
return;
} /* end of do_rawcall_tests() */
/***************************************************************************
* FUNCTION: DO_NCOPY1_TESTS *
* *
* DESCRIPTION: *
* *
* Tests normal copy functions (_XMMcopy() and macros). *
* *
* ENTRY: *
* *
* None. *
* *
* EXIT: *
* *
* Void. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void do_ncopy1_tests(void)
{
int handle = 0; /* dummy, to make some macros happy */
unsigned char far *realbuf;
unsigned char far *guard1, far *guard2, far *guard3;
unsigned char far *testbuf;
unsigned char far *testbuf2;
int status;
/* allocate a conventional memory buffer */
realbuf = (unsigned char far *) LMALLOC((MINFREE/1024L) + 3);
if (realbuf == (unsigned char far *) NULL)
{
printf("Can't allocate conventional buffer. Aborting.\n");
exit(3);
}
/*
** Since we can't access EMBs directly, the only way we have of getting
** data there is via the copy functions, which we're trying to test. So
** the first round of tests will copy data from one half of the
** conventional memory to the other, something which we can verify
** directly.
**
** Since _XMMcopy is symmetrical, we only need to give one direction
** a real workout.
*/
guard1 = realbuf;
FMEMSET(guard1, GUARDVAL, 1024);
testbuf = (unsigned char far *) normptr(guard1 + 1024);
guard2 = (unsigned char far *) normptr(testbuf + HALFLEN);
FMEMSET(guard2, GUARDVAL, 1024);
testbuf2 = (unsigned char far *) normptr(guard2 + 1024);
guard3 = (unsigned char far *) normptr(testbuf2 + HALFLEN);
FMEMSET(guard3, GUARDVAL, 1024);
gblmsg = " COPY TESTS CONVENTIONAL-CONVENTIONAL";
/* fill first buffer with incrementing words */
farincwordfill(testbuf, HALFLEN, 0);
/* fill second buffer with zero */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an even-length copy from offset 0 to offset 0 */
TESTHEADER();
printf("_XMMcopy(): even-length copy from offset 0 to offset 0.\n");
printf("Should succeed.\n");
status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
(unsigned long) testbuf2);
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
CPYWORDCHECK(testbuf2, 50);
ZEROCHECK((testbuf2 + 50), (HALFLEN - 50));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an even-length copy from offset 0 to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): even-length copy from offset 0 to arbitrary offset.\n");
printf("Should succeed.\n");
status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + 477));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 477);
MEMCMP(testbuf, (testbuf2 + 477), 50);
ZEROCHECK((testbuf2 + 477 + 50), ((HALFLEN - 477) - 50));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an even-length copy from offset 0 to just before the end */
TESTHEADER();
printf("_XMMcopy(): even-length copy from offset 0 to just before end.\n");
printf("Should succeed.\n");
status = _XMMcopy(50, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + HALFLEN - 50));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, (HALFLEN - 50));
CPYWORDCHECK((testbuf2 + HALFLEN - 50), 50);
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an even-length copy from arbitrary offset to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): even-length copy from arbitrary offset to ");
printf("arbitrary offset.\nShould succeed.");
status = _XMMcopy(50, 0, (unsigned long)(testbuf + 384), 0,
(unsigned long)(testbuf2 + 33333U));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 33333U);
MEMCMP((testbuf + 384), (testbuf2 + 33333U), 50);
ZEROCHECK((testbuf2 + 33333U + 50), ((HALFLEN - 33333U) - 50));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an even-length copy from just before the end to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): even-length copy from just before end to arbitrary.\n");
printf("Should succeed.\n");
status = _XMMcopy(50, 0, (unsigned long)(testbuf + HALFLEN - 50), 0,
(unsigned long)(testbuf2 + 7676));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 7676);
MEMCMP((testbuf + HALFLEN - 50), (testbuf2 + 7676), 50);
ZEROCHECK((testbuf2 + 7676 + 50), ((HALFLEN - 7676) - 50));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an odd-length copy from offset 0 to offset 0 */
TESTHEADER();
printf("_XMMcopy(): odd-length copy from offset 0 to offset 0.\n");
printf("Should succeed.\n");
status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
(unsigned long) testbuf2);
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
MEMCMP(testbuf, testbuf2, 111);
ZEROCHECK((testbuf2 + 111), (HALFLEN - 111));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an odd-length copy from offset 0 to offset misc */
TESTHEADER();
printf("_XMMcopy(): odd-length copy from offset 0 to arbitrary offset.\n");
printf("Should succeed.\n");
status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + 477));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 477);
MEMCMP(testbuf, (testbuf2 + 477), 111);
ZEROCHECK((testbuf2 + 477 + 111), ((HALFLEN - 477) - 111));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an odd-length copy from offset 0 to just before the end */
TESTHEADER();
printf("_XMMcopy(): odd-length copy from offset 0 to just before end.\n");
printf("Should succeed.\n");
status = _XMMcopy(111, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + HALFLEN - 111));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, (HALFLEN - 111));
MEMCMP(testbuf, (testbuf2 + HALFLEN - 111), 111);
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an odd-length copy from arbitrary offset to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): odd-length copy from arbitrary offset to ");
printf("arbitrary offset.\nShould succeed.\n");
status = _XMMcopy(111, 0, (unsigned long)(testbuf + 384), 0,
(unsigned long)(testbuf2 + 33333U));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 33333U);
MEMCMP((testbuf + 384), (testbuf2 + 33333U), 111);
ZEROCHECK((testbuf2 + 33333U + 111), ((HALFLEN - 33333U) - 111));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try an odd-length copy from just before the end to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): odd-length copy from just before end to arbitrary.\n");
printf("Should succeed.\n");
status = _XMMcopy(111, 0, (unsigned long)(testbuf + HALFLEN - 111), 0,
(unsigned long)(testbuf2 + 7676));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 7676);
MEMCMP((testbuf + HALFLEN - 111), (testbuf2 + 7676), 111);
ZEROCHECK((testbuf2 + 7676 + 111), ((HALFLEN - 7676) - 111));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try a one-byte copy from offset 0 to offset 0 */
TESTHEADER();
printf("_XMMcopy(): one-byte copy from offset 0 to offset 0.\n");
printf("Should succeed.\n");
status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
(unsigned long) testbuf2);
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
MEMCMP(testbuf, testbuf2, 1);
ZEROCHECK((testbuf2 + 1), (HALFLEN - 1));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try a one-byte copy from offset 0 to offset misc */
TESTHEADER();
printf("_XMMcopy(): one-byte copy from offset 0 to arbitrary offset.\n");
printf("Should succeed.\n");
status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + 477));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 477);
MEMCMP(testbuf, (testbuf2 + 477), 1);
ZEROCHECK((testbuf2 + 477 + 1), ((HALFLEN - 477) - 1));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try a one-byte copy from offset 0 to just before the end */
TESTHEADER();
printf("_XMMcopy(): one-byte copy from offset 0 to just before end.\n");
printf("Should succeed.\n");
status = _XMMcopy(1, 0, (unsigned long) testbuf, 0,
(unsigned long)(testbuf2 + HALFLEN - 1));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, (HALFLEN - 1));
MEMCMP(testbuf, (testbuf2 + HALFLEN - 1), 1);
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try a one-byte copy from arbitrary offset to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): one-byte copy from arbitrary offset to ");
printf("arbitrary offset.\nShould succeed.");
status = _XMMcopy(1, 0, (unsigned long)(testbuf + 384), 0,
(unsigned long)(testbuf2 + 33333U));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 33333U);
MEMCMP((testbuf + 384), (testbuf2 + 33333U), 1);
ZEROCHECK((testbuf2 + 33333U + 1), ((HALFLEN - 33333U) - 1));
TESTTAILER();
/* restore destination pattern */
FMEMSET(testbuf2, 0, HALFLEN);
/* try a one-byte copy from just before the end to arbitrary offset */
TESTHEADER();
printf("_XMMcopy(): one-byte copy from just before end to arbitrary.\n");
printf("Should succeed.\n");
status = _XMMcopy(1, 0, (unsigned long)(testbuf + HALFLEN - 1), 0,
(unsigned long)(testbuf2 + 7676));
TRIPLECHECK("_XMMcopy()", status, 0, (void far *) realbuf, 0, 0);
GUARDCHECK(0);
SRCWORDCHECK(testbuf, HALFLEN);
ZEROCHECK(testbuf2, 7676);
MEMCMP((testbuf + HALFLEN - 1), (testbuf2 + 7676), 1);
ZEROCHECK((testbuf2 + 7676 + 1), ((HALFLEN - 7676) - 1));
TESTTAILER();
/*
** Clean up.
*/
LFREE(realbuf);
return;
} /* end of do_ncopy1_tests() */
/*
** The following group of functions {test_XMM*()} are wrapper functions
** that call the XMSIF function named and perform preliminary checks on
** the return values. This keeps code size down since the check only has
** to be coded in one place.
*/
/***************************************************************************
* FUNCTION: TEST_XMMCORELEFT *
* *
* DESCRIPTION: *
* *
* This function calls XMSIF function XMMcoreleft() and checks the *
* return value to see if it is a multiple of 1024 (the minimum XMS *
* allocation unit). *
* *
* ENTRY: *
* *
* Void. *
* *
* EXIT: *
* *
* Returns the value returned by XMMcoreleft(). *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
unsigned long test_XMMcoreleft(void)
{
unsigned long xmsfree;
/* call XMMcoreleft and check error code */
xmsfree = XMMcoreleft();
weirdcodechk("XMMcoreleft()", 0, (void far *) NULL, 0, 0);
/* check if free byte count is multiple of 1024 */
if ((xmsfree % 1024L) != 0)
{
printf("XMMcoreleft() returned strange number %lu.\n", xmsfree);
exit(3);
}
return xmsfree;
} /* end of test_XMMcoreleft() */
/***************************************************************************
* FUNCTION: TEST_XMMALLCORELEFT *
* *
* DESCRIPTION: *
* *
* This function calls XMSIF function XMMallcoreleft() and checks *
* the return value to see if it is a multiple of 1024 (the minimum *
* XMS allocation unit). *
* *
* ENTRY: *
* *
* Void. *
* *
* EXIT: *
* *
* Returns the value returned by XMMallcoreleft(). *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
unsigned long test_XMMallcoreleft(void)
{
unsigned long xmsfree;
/* call XMMallcoreleft and check error code */
xmsfree = XMMallcoreleft();
weirdcodechk("XMMallcoreleft()", 0, (void far *) NULL, 0, 0);
/* check if free byte count is multiple of 1024 */
if ((xmsfree % 1024L) != 0)
{
printf("XMMallcoreleft() returned strange number %lu.\n", xmsfree);
exit(3);
}
return xmsfree;
} /* end of test_XMMallcoreleft() */
/***************************************************************************
* FUNCTION: TEST_XMMALLOC *
* *
* DESCRIPTION: *
* *
* This function calls XMSIF function XMMalloc() and checks the *
* return codes. *
* *
* ENTRY: *
* *
* bytes - bytes of XMS to allocate *
* *
* EXIT: *
* *
* Returns the handle returned by XMMalloc(). *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
int test_XMMalloc(unsigned long bytes)
{
int handle;
/* call XMMalloc() and check the return */
handle = XMMalloc(bytes);
weirdcodechk("XMMalloc()", 0, (void far *) NULL, 0, 0);
return handle;
} /* end of test_XMMalloc() */
/***************************************************************************
* FUNCTION: TEST_XMMREALLOC *
* *
* DESCRIPTION: *
* *
* This function calls XMSIF function XMMrealloc() and checks the *
* return codes. *
* *
* ENTRY: *
* *
* handle - XMS handle to reallocate *
* bytes - new size of XMS block *
* *
* EXIT: *
* *
* Returns the handle returned by XMMrealloc(), which is the same as *
* the argument handle. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
int test_XMMrealloc(int handle, unsigned long bytes)
{
int newhandle;
/* call XMMrealloc() and check the return */
newhandle = XMMrealloc(handle, bytes);
weirdcodechk("XMMrealloc()", 0, (void far *) NULL, 0, 0);
if (newhandle != handle)
{
printf("Passed handle %d to XMMrealloc(), got handle %d back.\n",
handle, newhandle);
XMMfree(handle);
exit(3);
}
return newhandle;
} /* end of test_XMMrealloc() */
/***************************************************************************
* FUNCTION: TEST_XMMFREE *
* *
* DESCRIPTION: *
* *
* This function calls XMSIF function XMMfree() and checks the *
* return codes. *
* *
* ENTRY: *
* *
* handle - XMS EMB handle to be freed *
* *
* EXIT: *
* *
* Void. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void test_XMMfree(int handle)
{
int status;
/* call XMMfree() and check the return */
status = XMMfree(handle);
TRIPLECHECK("XMMfree()", status, 0, (void far *) NULL, 0, 0);
return;
} /* end of test_XMMfree() */
/*
** The following group of functions are used to speed up return checking
** and keep code size down, since the return check only has to be coded
** in one place. They are used in various macros to further compact and
** clarify the code.
*/
/***************************************************************************
* FUNCTION: WEIRDRETCHK *
* *
* DESCRIPTION: *
* *
* This function checks to see if the status value passed to it is *
* either 0 or XMMOOPS, and assumes something has gone wrong if it *
* is not. If something has gone wrong, does some clean up before *
* exiting. *
* *
* ENTRY: *
* *
* function - name of function which may have goofed *
* status - status value to check *
* tofree1 - conventional memory block to be freed on exit. Not *
* freed if NULL. *
* tofree2 - XMS handle to be freed on exit. Not freed if 0. *
* tofree2 - another XMS handle to be freed on exit. Not freed if 0. *
* *
* EXIT: *
* *
* Void, or may not return. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void weirdretchk(char *function, int status, void far *tofree1, int tofree2,
int tofree3)
{
if ((status != XMMOOPS) && (status != 0))
{
printf("%s returned weird value %d, code 0x%X.\n", function, status,
(unsigned int) _XMMerror);
if (tofree1 != (void far *) NULL)
{
LFREE(tofree1);
}
if (tofree2 != 0)
{
XMMfree(tofree2);
}
if (tofree3 != 0)
{
XMMfree(tofree3);
}
exit(3);
}
return;
} /* end of weirdretchk() */
/***************************************************************************
* FUNCTION: WEIRDCODECHK *
* *
* DESCRIPTION: *
* *
* This function checks to see if the XMSIF error code value matches *
* the expected value, and assumes something has gone wrong if it *
* does not. If something has gone wrong, does some clean up before *
* exiting. *
* *
* ENTRY: *
* *
* function - name of function which may have goofed *
* expected - expected value of _XMMerror *
* tofree1 - conventional memory block to be freed on exit. Not *
* freed if NULL. *
* tofree2 - XMS handle to be freed on exit. Not freed if 0. *
* tofree2 - another XMS handle to be freed on exit. Not freed if 0. *
* *
* EXIT: *
* *
* Void, or may not return. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void weirdcodechk(char *function, int expected, void far *tofree1, int tofree2,
int tofree3)
{
if ((int) _XMMerror != expected)
{
printf("%s returned unexpected code 0x%X.\n", function,
(unsigned int) _XMMerror);
if (tofree1 != (void far *) NULL)
{
LFREE(tofree1);
}
if (tofree2 != 0)
{
XMMfree(tofree2);
}
if (tofree3 != 0)
{
XMMfree(tofree3);
}
exit(3);
}
return;
} /* end of weirdcodechk() */
/***************************************************************************
* FUNCTION: FAILCHECK *
* *
* DESCRIPTION: *
* *
* This function checks to see if the status value passed to it is *
* XMMOOPS and exits if it is. failcheck() is used when a function *
* is expected to succeed. Does some clean up before exiting. *
* *
* ENTRY: *
* *
* function - name of function which may have goofed *
* status - status value to be checked *
* tofree1 - conventional memory block to be freed on exit. Not *
* freed if NULL. *
* tofree2 - XMS handle to be freed on exit. Not freed if 0. *
* tofree2 - another XMS handle to be freed on exit. Not freed if 0. *
* *
* EXIT: *
* *
* Void, or may not return. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void failcheck(char *function, int status, void far *tofree1, int tofree2,
int tofree3)
{
if (status == XMMOOPS)
{
printf("%s failed, code 0x%X.\n", function, (unsigned int) _XMMerror);
if (tofree1 != (void far *) NULL)
{
LFREE(tofree1);
}
if (tofree2 != 0)
{
XMMfree(tofree2);
}
if (tofree3 != 0)
{
XMMfree(tofree3);
}
exit(3);
}
return;
} /* end of failcheck() */
/***************************************************************************
* FUNCTION: NOFAILCHECK *
* *
* DESCRIPTION: *
* *
* This function checks to see if the status value passed to it is *
* 0 and exits if it is. nofailcheck() is used when a function is *
* expected to fail. Does some clean up before exiting. *
* *
* ENTRY: *
* *
* function - name of function which may have goofed *
* status - status value to be checked *
* tofree1 - conventional memory block to be freed on exit. Not *
* freed if NULL. *
* tofree2 - XMS handle to be freed on exit. Not freed if 0. *
* tofree2 - another XMS handle to be freed on exit. Not freed if 0. *
* *
* EXIT: *
* *
* Void, or may not return. *
* *
* CONSTRAINTS/SIDE EFFECTS: *
* *
***************************************************************************/
void nofailcheck(char *function, int status, void far *tofree1, int tofree2,
int tofree3)
{
if (status == 0)
{
printf("%s did not fail.\n", function);
if (tofree1 != (void far *) NULL)
{
LFREE(tofree1);
}
if (tofree2 != 0)
{
XMMfree(tofree2);
}
if (tofree3 != 0)
{
XMMfree(tofree3);
}
exit(3);
}
return;
} /* end of nofailcheck() */